<?php

require_once('FachadaOP.php');

class ObjetoPersistente {
  public $id;
  public static $verbose_name;
  public static $verbose_plural;
  public static $__table_name;


  function __construct($atributos = array()) {
    self::$__table_name = Fachada::class_to_table(get_class($this));

    // Como al parecer en php no puedo tener named arguments
    // entonces habr� un argumento que sera un arreglo
    // asociativo con los nombres de cada argumento
    // en el objeto logico.
    //
    // To-Do: Hacer que si algo falla entonces muera el proceso
    // con un error entendible.
    $object_attrs = get_object_vars($this);
    if (!empty($atributos) ) {
      foreach($atributos as $name => $value) {
	if (array_key_exists($name, $object_attrs))
	  $this->$name = $value;
      }
    }
  }

  public function getAttrs() {
    /*
      Obtiene los atributos importantes del objeto. Esto quiere decir
      que obtiene todos los atributos especificados en la subclase a
      la que pertence el objeto que esta llamando al metodo, pero obvia
      los atributos que son especificados en la superclase
      ObjetoLogico.
     */
    $attrs = get_object_vars($this);
    $res = array();
    foreach ($attrs as $name => $value) {
      if (!($name == 'id' or $name == 'manager' or $name == '__table_name'
	    or $name == 'verbose_name' or $name == 'verbose_plural'))
	$res[$name] = $value;
    }
    return $res;
  }


  public function getID() {
    /*
      Devuelve el primary key (id) de la instancia si no se tiene y no se
      quieren colocar repeticiones en las bases de datos.

      Este metodo es experimental.
     */
    $attrs = $this->getAttrs();
    $query = "SELECT * FROM ".self::$__table_name." WHERE ";
    foreach ($attrs as $att => $value) {
      $query .= $att." = '".$value."' AND ";
    }
    $query = substr($query, 0, -5);

    $man = new dbManager();
    $man->conectar();
    $cursor = $man->crearCursor();

    $cursor->execute($query);

    if ($cursor->count())
      $pk = $cursor->fetchOne();
    else{
      return 0;
    }
    $man->desconectar();

    return $pk->id;
  }

  //--------------------------------------


  public function guardar() {
    /*
      Este metodo puede significar dos cosas. Si el objeto
      no tiene nada asignado en el atributo id quiere decir que
      estamos creando el objeto por primera vez, asi que llamamos
      al metodo insertarObjeto.
      Si el objeto tiene asignado un numero/codigo en el atributo
      id, quiere decir que el objeto ya ha sido creado, asi que
      llamamos a actualizarObjeto.

      Esto todavia esta buggy, buscar como mejorarlo.
     */
    // Crea o actualiza los campos del objeto
    //if ($this->getID() == 0) // o simplmente if (!$this->getID()) si no queremos permitir repeticiones
    if (!$this->id)
      return Fachada::insertarObjeto(self::$__table_name, $this);

    return Fachada::actualizarObjeto(self::$__table_name, $this);
  }
  
 public function borrar() {
    if ($this->id && Fachada::borrarObjeto(self::$__table_name, $this))
      return True;
    else
      return False;
  }


  // METODOS DE CLASE.
  public static function obtenerTodos() {
    return Fachada::obtenerTodos(self::$__table_name);
  }

  public static function filtrar($obj_field, $search_term) {

    // Verifico integridad de obj_field.
    if (array_key_exists($obj_field, get_class_vars(Fachada::table_to_class(self::$__table_name))))
      return Fachada::obtenerObjetoComo(self::$__table_name, $obj_field, $search_term);
    else
      die($obj_field . " not a field of " . self::$__table_name);

    // OJO: aqui falta verificar que los '$name's sean
    // en verdad atributos de la clase que esta llamando
    // al metodo.
  }

  public static function filtrarVarios($fields) {
    /*
      Recibe un arreglo asociativo de campos y los filtra
      no-estrictamente
     */
    $res = array();
    foreach ($fields as $name => $value) {
      $temp = Fachada::obtenerObjetoComo(self::$__table_name, $name, $value);
      if ($temp)
	$res = array_merge($temp, $res);
    }
    return $res;
  }

  public static function filtrarPorID($id) {
    return Fachada::obtenerObjeto(self::$__table_name, $id);
  }


  public static function filtrarPorIDs($ids_array) {
    // Lo mismo que filtrarPorID pero recibe un arreglo de ids, ejemplo:
    // filtrarPorIDs(array(1,4,5,6,12))
    $res = array();
    foreach($ids_array as $id) {
      $temp = Fachada::obtenerObjeto(self::$__table_name, $id);
      if ($temp)
	  $res = array_merge($temp, $res);
    }
    return $res;
  }

  public static function filtrarEstricto($obj_field, $search_term) {
    return Fachada::obtenerObjetoEstricto(self::$__table_name, $obj_field, $search_term);
  }

  public static function filtrarVariosEstricto($fields) {
    /*
      Recibe un arreglo asociativo de campos y los filtra
      estrictamente

    $res = array();
    foreach ($fields as $name => $value) {
      $temp = Fachada::obtenerObjetoEstricto(self::$__table_name, $name, $value);
      if ($temp)
	$res = array_merge($temp, $res);
    }
    return $res;
     */
    return Fachada::obtenerObjetoEstrictoPorCampos(self::$__table_name, $fields);
  }

  public static function obtenerUltimo($datetime_field) {
    // OJO, falta filtrar que datetime_field sea de verdad
    // un field que contenga datetime objs... ?
    return Fachada::obtenerUltimo(self::$__table_name, $date_time_field);
  }

  public static function obtenerOrdenados($obj_field) {
    return Fachada::obtenerOrdenados(self::$__table_name, $obj_field);
  }

  public static function obtenerOrdenadosDonde($obj_ord, $search_term, $obj_field,$asc) {
    return Fachada::obtenerOrdenadosDonde(self::$__table_name, $obj_ord, $search_term." = ".$obj_field,$asc);
  }

  //Busqueda Modelo
    public function BusquedaM($bus,$id){
        return Fachada::BusquedaModelo($bus, self::$__table_name, $id);
    }

  //Busqueda
    public function BusquedaS($bus){
     $trozos=explode(" ",$bus);
     $numero=count($trozos);
     if ($numero==1){
        //SI SOLO HAY UNA PALABRA DE BUSQUEDA SE ESTABLECE UNA INSTRUCION CON LIKE
        return Fachada::BusquedaSaoa2($bus,self::$__table_name);
     }elseif ($numero>1) {
        //SI HAY UNA FRASE SE UTILIZA EL ALGORTIMO DE BUSQUEDA AVANZADO DE MATCH AGAINST
        //busqueda de frases con mas de una palabra y un algoritmo especializado
        return Fachada::BusquedaSaoa($bus,self::$__table_name);
     }
     return false;
    }

    public function BusquedaSA($bus,$t){
     return Fachada::BusquedaAvanzadaSaoa($bus,$t,self::$__table_name);
    }
	
	public function obtenerObjetoEstricto($tableP, $obj_fieldP, $search_termP){
	
		return Fachada::obtenerObjetoEstricto($tableP, $obj_fieldP, $search_termP);
		
	}


}

?>
